<?php


namespace app\admin\controller\mall;


use app\admin\model\MallGoods;
use app\admin\traits\Curd;
use app\common\controller\AdminController;
use app\common\model\MallCate;
use app\common\model\MallDoorGoods;
use app\common\model\MallGoodsSku;
use app\common\model\MallManager;
use app\common\model\MallManagerDoor;
use app\common\model\MallSpecsValue;
use app\common\model\MallTags;
use EasyAdmin\annotation\ControllerAnnotation;
use EasyAdmin\annotation\NodeAnotation;
use EasyAdmin\tool\CommonTool;
use jianyan\excel\Excel;
use think\App;
use think\Exception;
use think\facade\Db;
use think\facade\Log;
use think\Validate;

/**
 * Class Goods
 * @package app\admin\controller\mall
 * @ControllerAnnotation(title="商城商品管理")
 */
class Goods extends AdminController
{

    use Curd;
    protected $relationSearch = true;
    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->model = new MallGoods();
    }

    /**
     * @NodeAnotation(title="列表")
     */
    public function index()
    {
        $manager_id =$this->request->param('id',0,'intval');
        $type =$this->request->param('type',0,'intval');
        if ($this->request->isAjax()) {
            if (input('selectFields')) {
                return $this->selectList();
            }
            list($page, $limit, $where) = $this->buildTableParames();
            if($manager_id > 0){
                $where[] =[['manager_id','=',$manager_id]];
            }
            $count = $this->model
                ->withJoin('cate', 'LEFT')
                ->where($where)
                ->count();
            $list = $this->model
                ->withJoin('cate', 'LEFT')
                ->where($where)
                ->page($page, $limit)
                ->order($this->sort)
                ->select();
            $data = [
                'code'  => 0,
                'msg'   => '',
                'count' => $count,
                'data'  => $list,
            ];
            return json($data);
        }
        $this->assign('manager_id',$manager_id);
        $this->assign('type',$type);
        return $this->fetch();
    }
    /**
     * @NodeAnotation(title="获取在售商品")
     */
    public function  getGoodsOnsalesList(){
        $list =$this->model->field('id,title')->where([['status','=',1]])->select()->toArray();
        $this->success('ok',$list);
    }


    /**
     * @NodeAnotation(title="添加")
     */
    public function add()
    {
        $manager_id =$this->request->param('id',0,'intval');
        $type =$this->request->param('type',0,'intval');
        if ($this->request->isPost()) {
            $post = $this->request->post();
            $validate = new Validate();
            $validate->rule([
                'cate_id|商品分类'  => 'require|number',
                'title|商品名称'  => 'require',
                'manager_id|所属商家'  => 'require',
                'doors|商家门店'  => 'require',
                'tags|商品标签'  => 'require',
                'logo|商品封面图'  => 'require',
                'images|商品图片'  => 'require',
                'buy_times|可购买时间'  => 'require',
                'hx_times|可核销时间'  => 'require',
                'content|商品详情'  =>'require',
                'buydesc|购买须知'  =>'require'
            ]);
            if(!$validate->check($post)){
                //打印错误规则，并返回页
                $this->error($validate->getError());
            }
            $rule = [];
            $this->validate($post, $rule);
            if($post['islimit'] ==1 && $post['limitnum'] ==0){
                $this->error("限购数量不能为0");
            }
            //判断规格
            if ($post['specifications'] == 0) {
                if (empty($post['market_price'])) {
                    $this->error("请输入市场价");
                }
                if (empty($post['goods_price'])) {
                    $this->error("请输入卖价");
                }

            } else {
                if (empty($post['skus'])) {
                    $this->error("请添加规格");
                }
            }
            try {
                //添加入库
                if ($post['specifications'] == 0) {
                    //单品
                    $insId = $this->model->save($post);
                    if ($insId) {
                        $goods_id=$p_id = $this->model->id;

                        $skus = [
                            "goods_id" => $p_id,
                            "stock" => $post['stock'],
                            "image" => $post['logo'],
                            "market_price" => $post['market_price'],
                            "price" => $post['goods_price'],
                            "is_dan" => 1,
                            "cost_price" => $post['cost_price'],
                            "create_time"=>time(),
                            "update_time"=>time()
                        ];
                        $saveIds = (new MallGoodsSku())->insertGetId($skus);
                        if ($saveIds) {
                            $update_data = [
                                "sku_id" => $saveIds,
                            ];
                            $result = $this->model->where([['id','=',$p_id]])->save($update_data);

                        } else {
                            throw new Exception("添加sku表失败");
                        }

                    } else {
                        throw new Exception("添加商品表失败");
                    }
                } else {

                    $insId = $this->model->save($post, true);
                    if ($insId) {
                        $skus = [];
                        $goods_id=$res_id = $this->model->id;

                        foreach ($post['skus'] as $k => $v) {
                            if (empty($picture)) {
                                $picture = $post['logo'];
                            }
                            $skus[] = [
                                "image" => $picture,
                                "goods_id" => $res_id,
                                "stock" => $v['stock'],
                                "price" => $v['price'],
                                "market_price" => $v['market_price'],
                                "cost_price" => $v['cost_price'],
                                "status" => $v['status'],
                                "specs_value_ids" => $k,
                                "create_time"=>time(),
                                "update_time"=>time()
                            ];

                        }
                        if (empty($skus)) {
                            throw new Exception("系统内部错误");
                        }
                        //添加库存
                        $res = (new MallGoodsSku())->saveAll($skus);
                        $update_data = [];
                        if ($res) {
                            $update_data['stock'] = array_sum(array_column($skus, 'stock'));
                            $update_data['goods_price'] = $skus[0]['goods_price'];
                            $update_data['market_price'] = $skus[0]['market_price'];
                            $update_data['cost_price'] = $skus[0]['cost_price'];
                            $update_data['total_stock'] = array_sum(array_column($skus, 'stock'));
                            $update_data['sku_id'] = $res[0]['id'];
                        }
                        $result = $this->model->where([['id','=',$res_id]])->save( $update_data);
                    }
                }


                $doors=explode(',',$post['doors']);
                $doordata =[];
                foreach($doors as $k=>$v){
                    $doordata[]=['goods_id'=>$goods_id,'door_id'=>$v];
                }
                (new MallDoorGoods())->saveAll($doordata);

                $this->model->commit();
            } catch (\Exception $e) {
                Log::error($e->getMessage() . " " . $e->getFile() . " " . $e->getLine());
                $this->model->rollback();
                $this->error($e->getMessage());
            }
            if ($result) {
                $this->success("操作成功");
            } else {
                $this->error("操作失败");
            }
        }
        $this->assign('mid',$manager_id);
        $this->assign('type',$type);
        return $this->fetch();
    }
    /**
     * @NodeAnotation(title="编辑")
     */
    public function edit($id)
    {
        $row = $this->model->find($id);
        $type =$this->request->param('type',0,'intval');
        empty($row) && $this->error('数据不存在');
        if ($this->request->isPost()) {
            $post = $this->request->post();

            $validate = new Validate();
            $validate->rule([
                'cate_id|商品分类'  => 'require|number',
                'title|商品名称'  => 'require',
                'manager_id|所属商家'  => 'require',
                'doors|商家门店'  => 'require',
                'tags|商品标签'  => 'require',
                'logo|商品封面图'  => 'require',
                'images|商品图片'  => 'require',
                'buy_times|可购买时间'  => 'require',
                'hx_times|可核销时间'  => 'require',
                'content|商品详情'  =>'require',
                'buydesc|购买须知'  =>'require'
            ]);
            if(!$validate->check($post)){
                //打印错误规则，并返回页
                $this->error($validate->getError());
            }
            $rule = [];
            $this->validate($post, $rule);
            if($post['islimit'] ==1 && $post['limitnum'] ==0){
                $this->error("限购数量不能为0");
            }

            if ($post['specifications'] == 0) {
                if (empty($post['market_price'])) {
                    $this->error("请输入市场价");
                }
                if (empty($post['goods_price'])) {
                    $this->error("请输入卖价");
                }

                if (empty($post['total_stock'])) {
                    $this->error("请输入总库存");
                }
            } else {
                if (empty($post['skus'])) {
                    $this->error("请添加规格");
                }
            }

            $post['id'] = $id;
            $this->model->startTrans();
            try {
                if ($post['specifications'] == 0) {
                    //单品
                    $update_goods = [
                        "cate_id" => $post['cate_id'],
                        "manager_id" => $post['manager_id'],
                        "doors" => $post['doors'],
                        "tags" => $post['tags'],
                        "title" => $post['title'],
                        "short_title" => $post['short_title'],
                        "logo" => $post['logo'],
                        "specifications" => $post['specifications'],
                        "images" => $post['images'],
                        "content" => $post['content'],
                        "buydesc" => $post['buydesc'],
                        "sort" => $post['sort'],
                        "islimit" => $post['islimit'],
                        "limitnum" => $post['limitnum'],
                        "perlimitnum" => $post['perlimitnum'],
                        "market_price" => $post['market_price'],
                        "cost_price" => $post['cost_price'],
                        "goods_price" => $post['goods_price'],
                        "sales" => $post['sales'],
                        "update_time"=>time()
                    ];

                    $insId = $this->model->where('id',$post['id'])->save($update_goods);
                    if ($insId) {
                        $p_id = $post['id'];
                        $skus = [
                            "goods_id" => $p_id,
                            "stock" => $post['stock'],
                            "image" => $post['logo'],
                            "market_price" => $post['market_price'],
                            "price" => $post['goods_price'],
                            "is_dan" => 1,
                            "cost_price" => $post['cost_price'],
                        ];
                        (new MallGoodsSku())->where('goods_id', $post['id'])->delete();
                        $saveIds = (new MallGoodsSku())->insertGetId($skus);
                        if ($saveIds) {
                            $update_data = [
                                "sku_id" => $saveIds,
                            ];
                            $result = $this->model->where([['id','=',$p_id]])->save($update_data);

                        } else {
                            throw new Exception("编辑sku表失败");
                        }
                    } else {
                        throw new Exception("编辑商品表失败");
                    }

                }else{
                    //多规格
                    $update_goods = [
                        "cate_id" => $post['cate_id'],
                        "manager_id" => $post['manager_id'],
                        "doors" => $post['doors'],
                        "tags" => $post['tags'],
                        "title" => $post['title'],
                        "short_title" => $post['short_title'],
                        "logo" => $post['logo'],
                        "specifications" => $post['specifications'],
                        "images" => $post['images'],
                        "content" => $post['content'],
                        "buydesc" => $post['buydesc'],
                        "sort" => $post['sort'],
                        "islimit" => $post['islimit'],
                        "limitnum" => $post['limitnum'],
                        "perlimitnum" => $post['perlimitnum'],
                        "sales" => $post['sales'],
                        "update_time"=>time()
                    ];
                    $insId = $this->model->where('id', $post['id'])->update($update_goods);
                    if ($insId) {
                        $skus = [];
                        $res_id = $post['id'];
                        foreach ($post['skus'] as $k => $v) {
                            if (empty($picture)) {
                                $picture = $post['logo'];
                            }
                            $skus[] = [
                                "image" => $picture,
                                "goods_id" => $res_id,
                                "stock" => $v['stock'],
                                "price" => $v['price'],
                                "market_price" => $v['market_price'],
                                "cost_price" => $v['cost_price'],
                                "specs_value_ids" => $k
                            ];
                        }
                        if (empty($skus)) {
                            throw new Exception("系统内部错误");
                        }

                        //添加库存
                        (new MallGoodsSku())->where([['goods_id','=',$post['id']]])->delete();
                        $res = (new MallGoodsSku())->saveAll($skus);
                        $update_data = [];
                        if ($res) {
                            $update_data['stock'] = array_sum(array_column($skus, 'stock'));
                            $update_data['goods_price'] = $skus[0]['price'];
                            $update_data['market_price'] = $skus[0]['market_price'];
                            $update_data['cost_price'] = $skus[0]['cost_price'];
                            $update_data['total_stock'] = array_sum(array_column($skus, 'stock'));
                            $update_data['sku_id'] = $res[0]['id'];
                        }
                        $result = $this->model->where([['id','=',$id]])->save($update_data);
                    }
                }
                (new MallDoorGoods())->where("goods_id='$id'")->delete();
                $doors =explode(',',$post['doors']);
                $doordata =[];
                foreach($doors as $k=>$v){
                    $doordata[]=['goods_id'=>$id,'door_id'=>$v];
                }
                (new MallDoorGoods())->saveAll($doordata);
                $this->model->commit();
            } catch (\Exception $e) {
                Log::error($e->getMessage() . " " . $e->getFile() . " " . $e->getLine());
                $this->model->rollback();
                $this->error($e->getMessage());
            }
            $this->success("操作成功");
        }
        $row['content'] =htmlspecialchars_decode($row['content']);
        $row['buydesc'] =htmlspecialchars_decode($row['buydesc']);

        //查询sku
        $sku = (new MallGoodsSku())->where("goods_id", $id)->select()->order('id desc')->toArray();
        $tree = [];
        if (!empty($sku)) {
            $skus = [];
            foreach ($sku as $v) {
                $skus[] = explode('-', $v['specs_value_ids']);
            }
            $sku_value = [];
            if (!empty($skus)) {
                foreach ($skus as $v) {
                    foreach ($v as $item) {
                        $sku_value[] = $item;
                    }
                }
            }
            $value = (new MallSpecsValue())->alias('c')
                ->field('c.id,c.title,c.specs_id,b.title as specs_title')
                ->join('mall_specs b', 'b.id = c.specs_id')
                ->where('c.id', 'in', $sku_value)
                ->select()->toArray();
            $specs_values = [];
            $specs_value = (new MallSpecsValue())
                ->alias('c')
                ->field('c.id,c.title,c.specs_id,b.title as specs_title')
                ->join('mall_specs b', 'b.id = c.specs_id')
                ->where('specs_id', 'in', array_column($value, 'specs_id'))
                ->select()
                ->toArray();
            foreach ($specs_value as $k => $v) {
                $specs_values[$k] = $v;
                $specs_values[$k]['checked'] = '';
                foreach ($value as $j) {
                    if ($v['specs_id'] == $j['specs_id'] && $v['id'] == $j['id']) {
                        $specs_values[$k]['checked'] = 'checked';
                    }
                }
            }
            $tree = getTreeSpecs($specs_values);
        }
        $sku_data = [];
        foreach ($sku as $value) {
            $sku_data[$value['specs_value_ids']] = $value;
        }

        $this->assign([
            "tree" => $tree,
            "sku" => $sku_data,
            "id" => $id,
            "row"=>$row,
            "type"=>$type
        ]);
        return $this->fetch();
    }
    /**
     * @NodeAnotation(title="初始化规格")
     */
    public function getGoodscates(){
        $id = $this->request->param('id', 0, 'intval');
        if ($id == 0) {
            $this->error("发生错误");
        }
        $goods=$this->model->find($id);
        if(!$goods){
            $this->error("商品不存在");
        }


        $sku = (new MallGoodsSku())->where("goods_id", $id)
            ->select()
            ->toArray();
        $sku_data = [];
        foreach ($sku as $value) {
            $sku_data[$value['specs_value_ids']] = $value;
        }

        $this->success('ok', ['sku_data'=>$sku_data]);
    }

    /**
     * @NodeAnotation(title="规格")
     */
    public function dialog()
    {
        return $this->fetch();
    }

    /**
     * @NodeAnotation(title="初始化选择门店与标签")
     */
    public function getInfo(){
        $id =$this->request->param('id','','intval');
        $info =$this->model->find($id);
        empty($info) && $this->error('数据不存在');
        $tags =explode(',',$info['tags']);
        $doors =explode(',',$info['doors']);
        $tagss =[];
        $doorss =[];
        foreach ($tags as $k=>$v){
            $taginfo=(new MallTags())->where([['id','=',$v]])->find();
            $tagss[$k]['name'] =!empty($taginfo)?$taginfo['title']:'';
            $tagss[$k]['value']=$v;
        }
        foreach ($doors as $kk=>$vv){
            $doorinfo=(new MallManagerDoor())->where([['id','=',$vv]])->find();
            $doorss[$kk]['name'] =!empty($doorinfo)?$doorinfo['title']:'';
            $doorss[$kk]['value']=$vv;
        }
        $this->success('返回成功',['tags'=>$tagss,'doors'=>$doorss]);
    }

    /**
     * @NodeAnotation(title="导出")
     */
    public function export()
    {
        list($page, $limit, $where) = $this->buildTableParames();
        $tableName = $this->model->getName();
        $tableName = CommonTool::humpToLine(lcfirst($tableName));
        $prefix = config('database.connections.mysql.prefix');
        $dbList = Db::query("show full columns from {$prefix}{$tableName}");
        $header = [];
        foreach ($dbList as $vo) {
            $comment = !empty($vo['Comment']) ? $vo['Comment'] : $vo['Field'];
            if (!in_array($vo['Field'], $this->noExportFields)) {
                $header[] = [$comment, $vo['Field']];
            }
        }
        $list = $this->model
            ->where($where)
            ->limit(100000)
            ->order('id', 'desc')
            ->select()
            ->toArray();
        foreach ($list as $k=>$v){
            $manager =(new MallManager())->find($v['manager_id']);
            $list[$k]['manager_id'] =!empty($manager)?$manager['title']:'';
            $cate =(new MallCate())->find($v['cate_id']);
            $list[$k]['cate_id'] =!empty($cate)?$cate['title']:'';
            $doorIds =explode(',',$v['doors']);
            $doornames ='';
            foreach ($doorIds as $kk=>$vv){
                $doorInfo =(new MallManagerDoor())->find($vv);
                $doornames.=!empty($doorInfo)?$doorInfo['title'].' ':' ';
            }
            $list[$k]['doors'] =$doornames;

            $tags =explode(',',$v['tags']);
            $tagnames ='';
            foreach ($tags as $kkk=>$vvv){
                $tagInfo =(new MallTags())->find($vv);
                $tagnames.=!empty($tagInfo)?$tagInfo['title'].' ':' ';
            }
            $list[$k]['tags'] =$tagnames;


            if($v['status'] ==1){
                $list[$k]['status'] ='上架';
            }else{
                $list[$k]['status'] ='下架';
            }
        }
        $fileName = time();
        return Excel::exportData($list, $header, $fileName, 'xlsx');
    }

}